package com.symaster.swingalixcomponent.tabs;

import com.symaster.alixanimation.Curve;
import com.symaster.alixanimation.util.AnimationUtil;

import javax.swing.*;
import java.awt.*;

import static com.symaster.alixanimation.util.TimeUtil.floatTime;

/**
 * @author yinmiao
 * @version 2023/12/4
 */
public class Scrollbar extends JComponent {
    private static final float times = 150f;
    private static final Curve curve = Curve.TYPE_FAST_TO_SLOW;
    private final PaintRunnable paintRunnable;
    private int viewIndex = 0;
    private Integer changeIndex;
    private Float changeTime;
    private boolean change = false;

    public Scrollbar() {
        this.paintRunnable = new PaintRunnable(this);
    }

    public int getViewIndex() {
        return viewIndex;
    }

    public void setViewIndex(int viewIndex) {
        int src = this.viewIndex;
        if (src == viewIndex) {
            return;
        }

        this.changeIndex = viewIndex;
        this.changeTime = floatTime();
        this.change = true;
        SwingUtilities.invokeLater(paintRunnable);
    }

    @Override
    public void paint(Graphics g) {
        Component[] components = getComponents();
        if (components.length > 0) {
            for (Component component : components) {
                component.setSize(getWidth(), getHeight());
            }

            int xOffset;
            if (this.change) {
                float v = floatTime() - changeTime;
                if (v >= times) {
                    this.viewIndex = changeIndex;
                    xOffset = -(getWidth() * viewIndex);
                    this.change = false;
                } else {
                    int srcPoint = -(this.viewIndex * getWidth());
                    int dstPoint = -(this.changeIndex * getWidth());
                    float point = (float) AnimationUtil.getPoint(curve, v / times);

                    float v1 = point * (dstPoint - srcPoint) + srcPoint;
                    xOffset = Math.round(v1);
                }
            } else {
                xOffset = -(getWidth() * viewIndex);
            }

            for (int i = 0; i < components.length; i++) {
                Component component = components[i];
                component.setBounds(i * getWidth() + xOffset, 0, getWidth(), getHeight());
                component.doLayout();
            }
        }

        super.paint(g);
        if (this.change) {
            SwingUtilities.invokeLater(paintRunnable);
        }
    }

    public static class PaintRunnable implements Runnable {

        private final Scrollbar scrollbar;

        public PaintRunnable(Scrollbar scrollbar) {
            this.scrollbar = scrollbar;
        }

        @Override
        public void run() {
            scrollbar.repaint();
        }
    }

}
